iT邦幫忙

0

在 Vue 3 中使用 Headless UI

  • 分享至 

  • xImage
  •  

Headless UI

介紹

最常在Tailwind的範例中看到它,支援Vue3、React兩大框架。(Vue只支援3)
特點1:純功能UI不帶有樣式
特點2:支援無障礙功能

安裝

npm install @headlessui/vue

在需要使用的組件中import就好

假設今天要做一個在父組件頁面打開子組件Modal視窗的效果
打開子組件Modal視窗

Dialog (Modal)

首先在父組件先引入需要用到的組件

import { Dialog, DialogPanel, TransitionRoot, TransitionChild } from '@headlessui/vue';
import pluginModel from '../components/plugnModel.vue';
// 這是要打開的子組件

避免瀏覽器跳警告我會在components中註冊他們

export default {
    components: {
        pluginModel, // 子組件
        Dialog, // 功能本體(開關在這,如果要全畫面暗掉的背景也放這)
        DialogPanel, // 視窗本人放這
        DialogTitle, // 告訴用戶的無障礙標題
        DialogDescription, // 告訴用戶的無障礙內容
        TransitionRoot, // 整個頁面的過渡動畫效果
        TransitionChild, // 單個組件的過渡動畫(須在TransitionRoot內使用)
    }
}

官方文件沒有動畫效果的範例可以參考✿這裡
但實際上不可能不加過渡的吧(吧?)
雖然說 Vue 中有內建的 Transition 效果
但他可以控制更細微的子組件動畫
所以讓我們加上上面提到的 TransitionRoot & TransitionChild

// 父組件
<template>
// 使用動畫需要將原本在Dialog的open開關改到TransitionRoot :show="isOpen"
// 注意是 :show 不是 :open
<TransitionRoot :show="isOpen" as="template" 
enter="duration-300 ease" enter-from="opacity-0" enter-to="opacity-100"
leave="duration-200 ease-in" leave-from="opacity-100" leave-to="opacity-0">
    <Dialog class="relative z-30" as="div" @close="closeModal"> // 注意這邊是@close
        <!-- Modal背景 -->
        <TransitionChild as="template" 
        enter="ease-out duration-300" enter-from="opacity-0" enter-to="opacity-100"
        leave="ease-in duration-200" leave-from="opacity-100" leave-to="opacity-0">
            // 直接點擊背景可以關閉視窗
            <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"
            aria-hidden="true" @click="closeModal" />
        </TransitionChild>
        <!-- Modal內容 -->
        <div class="fixed inset-0 overflow-y-auto">
            <div class="flex min-h-full items-center justify-center p-4 text-center">
            <!-- 上面兩行負責定位 -->
                <TransitionChild as="template" 
                enter="ease-out duration-500 transform"
                enter-from="opacity-0 -translate-y-40 sm:scale-95"
                enter-to="opacity-100 -translate-y-0 sm:scale-100" 
                leave="ease-in duration-200"
                leave-from="opacity-100 sm:scale-100" 
                leave-to="opacity-0 sm:scale-95">
                    <DialogPanel 
                    class="fixed top-20 h-5/6 overflow-y-auto w-11/12 bg-white rounded-lg md:w-8/12">
                        <!-- 子組件 -->
                    </DialogPanel>
                </TransitionChild>
            </div>
        </div>
    </Dialog>
</TransitionRoot>
</template>

上面會用到的資料、函式

export default {
    setup() {
        // 控制 Modal 開關
        let isOpen = ref(false);        
        // 關閉 Modal 
        function closeModal() {
            isOpen.value = false;
        }        
        return {
            isOpen,
            closeModal,
        }
    },
    components: {
        Dialog,
        DialogPanel,
        TransitionRoot,
        TransitionChild,
    },
}

子組件就包含DialogTitleDialogDescription
完成!


隨筆

官方說明文件很完整,但實作的時候常常漏東漏西
所以在這邊紀錄一下流程跟需要注意的地方


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言